import md5 from 'md5'
import { AxiosRequestConfig } from 'axios'
import useHttpRequest from '@/store/modules/httpRequest'
import { useRouter } from 'vue-router'
import service from './axios_create'
import { useRequestInterceptor, useResponseInterceptor } from './axios_interceptors'
import { BasePromiseResultType, RequestConfig } from '#/comm/service'

const router = useRouter()
const { CancelToken } = service
const clearSource = CancelToken.source()
const historyRequest: string[] = []
useResponseInterceptor(service)
useRequestInterceptor(service)
// 移除缓存中的请求
const removeHistoryRequest = (requestHash: string): void => {
  const requestIndex: number = historyRequest.findIndex((item) => item === requestHash)
  if (requestIndex > -1) {
    historyRequest.splice(requestIndex, 1)
  }
}
// 缓存请求
const cacheHistoryRequest = (requestHash: string): boolean => {
  const requestData: string | undefined = historyRequest.find((el) => el === requestHash)
  if (!requestData) {
    historyRequest.push(requestHash)
    return true
  }
  return false
}

// 公共请求方法
const commonRequest = <T>(
  method: any,
  url: string,
  params: any,
  data: any,
  headers?: any,
  responesData?: any,
): Promise<BasePromiseResultType<T>> => {
  const requestHash = md5(url + JSON.stringify(data || params) + JSON.stringify(headers))
  if (cacheHistoryRequest(requestHash) === true) {
    const requestConfig: RequestConfig = {
      method,
      url,
      data,
      params,
      headers,
      cancelToken: new CancelToken((c: any) => {
        const httpRequest = useHttpRequest()
        // 强行中断请求要用到的
        httpRequest.addHttpRequestList({
          key: router ? router.currentRoute.value.fullPath : requestHash,
          url,
          value: c,
        })
      }),
    }
    if (responesData) {
      Object.keys(responesData).forEach((item) => {
        requestConfig[item] = responesData[item]
      })
    }
    const promise: Promise<BasePromiseResultType<T>> = new Promise((resolve) => {
      service(requestConfig as AxiosRequestConfig)
        .then((res) => {
          resolve([res.data, null])
          removeHistoryRequest(requestHash)
        })
        .catch((err) => {
          resolve([null, err.message])
          removeHistoryRequest(requestHash)
        })
    })
    return promise
  }
  return Promise.resolve([null, '当前请求正在请求中,请稍后'])
}

const axios = {
  post: async <T>(url: string, data?: any, headers?: any, responesData?: any): Promise<BasePromiseResultType<T>> => {
    return commonRequest('post', url, null, data, headers, responesData)
  },
  export: async (url: string, data?: any, headers?: any, responesData?: any): Promise<any> => {
    return commonRequest('post', url, null, data, headers, responesData || { responseType: 'blob' })
  },
  get: async <T>(url: string, params?: any, headers?: any, responesData?: any): Promise<BasePromiseResultType<T>> => {
    return commonRequest('get', url, params, null, headers, responesData)
  },
  cancelRequest: () => {
    clearSource.cancel('Operation canceled by the user.')
  },
}
export default axios
